package com.itcast.service;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.itcast.config.ESConfig;
import com.itcast.pojo.GoodInfo;
import com.itcast.vo.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class WebService {

    @Autowired
    private ESConfig esConfig;


    public PageInfo queryByKeywordAndPage(String page,
                                          String size,
                                          String keyword,
                                          String price,
                                          String createTime) throws Exception {
        SearchRequest searchRequest = new SearchRequest("sku");

        //boolQueryBuilder
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        //boolQueryBuilder.should.matchQueryBuilder
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", keyword);
        boolQueryBuilder.should(matchQueryBuilder);

        if(StrUtil.isNotEmpty(price)) {
            String[] priceArr = price.split("-");
            RangeQueryBuilder queryBuilder = QueryBuilders.rangeQuery("price");
            queryBuilder.gte(priceArr[0]);
            if(priceArr.length > 1) {
                queryBuilder.lte(priceArr[1]);
                //boolQueryBuilder.filter
                boolQueryBuilder.filter(queryBuilder);
            } else {
                //boolQueryBuilder.filter
                boolQueryBuilder.filter(queryBuilder);
            }

        }

        //searchSourceBuilder.query.boolQueryBuilder
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.trackTotalHits(true);
        searchSourceBuilder.query(boolQueryBuilder);

        //高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("name");
        highlightBuilder.preTags("<font color='red'>");
        highlightBuilder.postTags("</font>");
        searchSourceBuilder.highlighter(highlightBuilder);

        //分页
        searchSourceBuilder.from(Integer.parseInt(page));
        searchSourceBuilder.size(Integer.parseInt(size));

        //按照价格升序排序
        //searchSourceBuilder.sort("price", SortOrder.ASC);

        //判断createTime,则按照创建时间倒序排序
        if(ObjectUtil.equal(createTime, "-1")) {
            searchSourceBuilder.sort("createTime", SortOrder.DESC);
        }

        searchRequest.source(searchSourceBuilder);

        SearchResponse searchResponse = esConfig.getRestHighLevelClient().search(searchRequest, RequestOptions.DEFAULT);

        PageInfo pageInfo = new PageInfo();
        long total = searchResponse.getHits().getTotalHits().value;
        pageInfo.setTotal(Convert.toInt(total));
        Integer totalPage = (Convert.toInt(total)+ Convert.toInt(size) - 1) / Convert.toInt(size);
        pageInfo.setPages(totalPage);
        pageInfo.setMsg("查询成功");
        pageInfo.setCode(10000);

        List<GoodInfo> data = new ArrayList<>();
        SearchHit[] subHits = searchResponse.getHits().getHits();
        for (SearchHit subHit : subHits) {
            Long id = Convert.toLong(subHit.getId());
            Map<String, Object> sourceAsMap = subHit.getSourceAsMap();

            Map<String, HighlightField> highlightFields = subHit.getHighlightFields();
            String title = null;
            if(ObjectUtil.isNotEmpty(highlightFields)) {
                HighlightField highlightField = highlightFields.get("name");
                Text[] fragments = highlightField.fragments();
                if (ObjectUtil.isNotEmpty(fragments)) {
                    title = StringUtils.join(fragments);
                }
            } else {
                title = Convert.toStr(sourceAsMap.get("name"));
            }
            Double goodPrice = Convert.toDouble(sourceAsMap.get("price"));
            String image = Convert.toStr(sourceAsMap.get("image"));
            data.add(new GoodInfo(id, title, goodPrice, image));
        }
        pageInfo.setData(data);
        return pageInfo;
    }

}
